<?php

namespace src;

use src\interfaces\IRequest;
use src\interfaces\IUploadFile;

class Request implements IRequest
{
    protected $get;
    protected $post;
    protected $cookies;
    protected $files;
    protected $method;
    protected $uri;
    protected $server;
    protected $headers;

    public function __construct($get = null, $post = null, $server = null, $cookies = null, $files = null)
    {
        $this->get = null === $get ? $_GET : $get;
        $this->post = null === $post ? $_POST : $post;
        $this->server = null === $server ? $_SERVER : $server;
        $this->cookies = null === $cookies ? $_COOKIE : $cookies;
        $this->files = null === $files ? $_FILES : $files;
        $this->initialize();
    }

    protected function initialize()
    {
        $this->body = fopen('php://input', 'r');
        $headers = [];
        foreach ($this->server as $key => $value) {
            if (0 === strpos($key, 'HTTP_')) {
                $key = strtolower(str_replace('_', '-', substr($key, 5)));
                $headers[$key] = $value;
            }
        }
        $this->headers = $headers;
    }

    public function getMethod()
    {
        if (null == $this->method) {
            $this->method = strtoupper($this->server['REQUEST_METHOD']);
        }
        return $this->method;
    }

    public function getUri()
    {
        if (!$this->uri) {
            $this->uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '/';
            if ($this->uri !== "/" && ($offset = strpos($this->uri, "?")) !== false){
                $this->uri = substr($this->uri, 0, $offset );
            }
        }
        return $this->uri;
    }

    public function post($key = null)
    {
       return isset($this->post[$key]) ? $this->post[$key] : null;
    }

    public function get($key = null)
    {
        return isset($this->get[$key]) ? $this->get[$key] : null;
    }

    public function header($key = null)
    {
        return isset($this->headers[$key]) ? $this->headers[strtolower($key)] : null;
    }

    public function servers()
    {
        return $this->server;
    }

    /**
     * @param $name
     * @return IUploadFile|null
     */
    public function file($name)
    {
        return isset($this->files[$name]) ? new UploadFile($this->files[$name])  : null;
    }
}